//===============================================================================
// Q4Tech Engineering Team
// Mobile Updater Application Block - November 2006
//===============================================================================
// Copyright  Q4Tech Informatica Argentina.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using Q4Tech.Engineering.UpdaterAgent.Management;
using System.Windows.Forms;
using Microsoft.WindowsMobile.Status;
using System.Drawing;

namespace Q4Tech.Engineering.UpdaterAgent.UpdaterView
{
    public class UpdaterViewPresenter
    {
        private ManifestListManager manager = new ManifestListManager();

        private string messageLog;
        private bool verbose;

        private bool attaching = false;
        Orientation currentOrientation;

        IUpdaterView view;

        public UpdaterViewPresenter()
        {
            manager.ActivationStarted += manager_ActivationStarted;
            manager.ActivationSuspended += manager_ActivationSuspended;
            manager.CheckForUpdatesStarted += manager_CheckForUpdatesStarted;
            manager.DownloadComplete += manager_DownloadComplete;
            manager.InfoAvailable += manager_InfoAvailable;
            manager.PendingUpdateResumed += manager_PendingUpdateResumed;
            manager.UpdateError += manager_UpdateError;
            manager.UpdateSuspended += manager_UpdateSuspended;
            manager.ConnectionStatusChanged += manager_ConnectionStatusChanged;
            manager.CheckForUpdatesFinished += manager_CheckForUpdatesFinished;
            manager.ActivationCompleted += manager_ActivationCompleted;

        }

        ~UpdaterViewPresenter()
        {
            manager.ActivationStarted -= manager_ActivationStarted;
            manager.ActivationSuspended -= manager_ActivationSuspended;
            manager.CheckForUpdatesStarted -= manager_CheckForUpdatesStarted;
            manager.DownloadComplete -= manager_DownloadComplete;
            manager.InfoAvailable -= manager_InfoAvailable;
            manager.PendingUpdateResumed -= manager_PendingUpdateResumed;
            manager.UpdateError -= manager_UpdateError;
            manager.UpdateSuspended -= manager_UpdateSuspended;
            manager.ConnectionStatusChanged -= manager_ConnectionStatusChanged;
            manager.CheckForUpdatesFinished -= manager_CheckForUpdatesFinished;
            manager.ActivationCompleted -= manager_ActivationCompleted;

        }

        public IUpdaterView View
        {
            get { return view; }
            set { view = value; AttachView(view); }
        }

        private void AttachView(IUpdaterView view)
        {
            view.ForceUpdate += view_ForceUpdate;
            view.VerboseCheck += view_VerboseCheck;
            view.ViewDeviceID += view_ViewDeviceID;
            view.LoadView += view_Load;
            view.OrientationChange += view_OrientationChange;
            view.ActiveView += view_ActiveView;

        }

        void view_ActiveView(object sender, BoolEventArgs e)
        {
            if (e.Value)
            {
                view.OrientationChange -= view_OrientationChange;
                view.OrientationChange += view_OrientationChange;

                if (!attaching)
                    SetProperView();
            }
            else
                view.OrientationChange -= view_OrientationChange;
        }

        void view_OrientationChange(object sender, ChangeEventArgs e)
        {
            AttachView();
        }

        private void AttachView()
        {
            attaching = true;

            SetProperView();

            attaching = false;

        }

        private void SetProperView()
        {
            SetProperView(false);
        }


        public void SetProperView(bool force)
        {
            IUpdaterView oldView = null;

            Size screenSize = Screen.PrimaryScreen.Bounds.Size;
            Orientation newOrientation = (screenSize.Width > screenSize.Height) ? Orientation.Horizontal : Orientation.Vertical;

            if (force || newOrientation != currentOrientation)
            {
                if (!force)
                {
                    oldView = view;
                    Dispose();
                }

                SaveStatus(view);

                if (newOrientation == Orientation.Horizontal)
                    View = new UpdaterViewLS();
                else
                    View = new UpdaterView();

                SetStatus();

                currentOrientation = newOrientation;
                view.Show();

                if (!force)
                    oldView.Hide();
            }

        }

        private void SetStatus()
        {
            if (!String.IsNullOrEmpty(messageLog))
                view.MessageLog = messageLog;
            view.VerboseSet = verbose;
        }

        private void SaveStatus(IUpdaterView view)
        {
            if (view != null)
                messageLog = view.MessageLog;
        }


        private void Dispose()
        {
            view.ForceUpdate -= view_ForceUpdate;
            view.VerboseCheck -= view_VerboseCheck;
            view.ViewDeviceID -= view_ViewDeviceID;
            view.LoadView -= view_Load;
            view.OrientationChange -= view_OrientationChange;
        }

        void view_Load(object sender, EventArgs e)
        {
            view.SetStatus(manager.IsConnected, manager.PendingDownloads);
        }

        void view_ViewDeviceID(object sender, EventArgs e)
        {
            MessageBox.Show(manager.DeviceId);
        }

        void view_VerboseCheck(object sender, BoolEventArgs e)
        {
            verbose = e.Value;
        }

        void view_ForceUpdate(object sender, EventArgs e)
        {
            manager.ForceCheckForUpdates();
        }

        void manager_ActivationStarted(object sender, ActivationStartedEventArgs args)
        {
            view.WriteLine(String.Format("Activating manifest for application:\r\n  {0}.", args.Manifest.Description));
        }

        void manager_ActivationSuspended(object sender, ActivationSuspendedEventArgs args)
        {
            view.WriteLine(String.Format("An activation has been suspended: {0}", args.Reason));
        }

        void manager_ActivationCompleted(object sender, ActivationCompletedEventArgs args)
        {
            if (args.Success)
                view.WriteLine(String.Format("Activation completed for {0}", args.Manifest.Description));
            else
                view.WriteLine(String.Format("Activation failed for {0}.", args.Manifest.Description));
        }

        void manager_CheckForUpdatesFinished(object sender, CheckForUpdatesFinishedEventArgs args)
        {
            view.SetStatus(manager.IsConnected, manager.PendingDownloads);
        }

        void manager_ConnectionStatusChanged(object sender, EventArgs args)
        {
            view.SetStatus(manager.IsConnected, manager.PendingDownloads);
        }

        void manager_UpdateSuspended(object sender, UpdateSuspendedEventArgs args)
        {
            view.WriteLine(String.Format("A download has been suspended: {0}", args.Reason));
        }

        void manager_UpdateError(object sender, UpdateErrorEventArgs args)
        {
            view.WriteLine("An error has ocurred: " + (String.IsNullOrEmpty(args.Error) ? args.Exception.Message : args.Error));

            view.SetStatus(manager.IsConnected, 0);
        }

        void manager_PendingUpdateResumed(object sender, PendingUpdateResumedEventArgs args)
        {
            view.WriteLine("Resuming suspended updates...");
        }

        void manager_InfoAvailable(object sender, InfoAvailableEventArgs args)
        {
            if (verbose || !args.Trivial)
                view.WriteLine(args.Info);
        }

        void manager_DownloadComplete(object sender, DownloadCompleteEventArgs args)
        {
            if (verbose)
                view.WriteLine("1 Download completed");

            view.SetStatus(manager.IsConnected, manager.PendingDownloads);

            if (verbose)
                view.WriteLine(String.Format("Download completed for manifest {0}.", args.Manifest.Description));

            if (manager.PendingDownloads > 0)
                view.WriteLine(String.Format("{0} downloads pending", manager.PendingDownloads));
            else
                view.WriteLine("No downloads pending.");
        }

        void manager_CheckForUpdatesStarted(object sender, CheckForUpdatesStartedEventArgs args)
        {
            view.ForceUpdateEnabled = false;
            view.WriteLine(new string('-', 39));
            view.WriteLine("Beginning check for updates");
        }

    }
}
